package com.yilin.tms.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yilin.commons.encrypt.EncryptUtils;
import com.yilin.commons.encrypt.Md5Util;
import com.yilin.commons.exception.BusinessException;
import com.yilin.commons.util.ArrayUtil;
import com.yilin.commons.util.StringUtil;
import com.yilin.tms.core.application.AppUtil;
import com.yilin.tms.core.application.PageData;
import com.yilin.tms.core.commons.base.BaseCode;
import com.yilin.tms.core.commons.model.AuthStatus;
import com.yilin.tms.core.commons.model.AuthStatusData;
import com.yilin.tms.core.commons.utils.ParamUtil;
import com.yilin.tms.core.commons.utils.QueryUtil;
import com.yilin.tms.core.components.redis.RedisClient;
import com.yilin.tms.core.components.redis.RedisKeys;
import com.yilin.tms.core.components.repository.OperateLogRepository;
import com.yilin.tms.core.entity.system.system.Jurisdiction;
import com.yilin.tms.core.entity.user.RoleType;
import com.yilin.tms.core.entity.user.UserType;
import com.yilin.tms.core.entity.user.account.Account;
import com.yilin.tms.core.entity.user.account.Contact;
import com.yilin.tms.core.entity.user.account.CreditRecord;
import com.yilin.tms.core.entity.user.account.UserAccrual;
import com.yilin.tms.core.entity.user.auth.*;
import com.yilin.tms.core.entity.user.organize.Cooperate;
import com.yilin.tms.core.entity.user.organize.Organize;
import com.yilin.tms.core.remote.ICapitalRemote;
import com.yilin.tms.core.remote.IGpsRemote;
import com.yilin.tms.core.remote.IMessageRemote;
import com.yilin.tms.core.remote.ISystemRemote;
import com.yilin.tms.user.mapper.AccountMapper;
import com.yilin.tms.user.mapper.ContactMapper;
import com.yilin.tms.user.mapper.CooperateMapper;
import com.yilin.tms.user.mapper.CreditRecordMapper;
import com.yilin.tms.user.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 服务实现类
 */
@Service
@Transactional
public class AccountService extends ServiceImpl<AccountMapper, Account> implements IAccountService {


    @Resource
    private AccountMapper accountMapper;
    @Resource
    private ContactMapper contactMapper;
    @Resource
    private CreditRecordMapper creditRecordMapper;
    @Resource
    private OperateLogRepository operateLogRepository;

    @Resource
    private IRoleService roleService;
    @Resource
    private IAuthService authService;
    @Resource
    private IOrganizeService organizeService;
    @Resource
    private IGrantFunctionApiService functionGrantService;
    @Resource
    private IGrantRoleMenuService grantRoleMenuService;
    @Resource
    private IMessageRemote messageRemote;
    @Resource
    private IGpsRemote gpsRemote;
    @Resource
    private ICapitalRemote capitalRemote;
    @Resource
    private CooperateMapper cooperateMapper;
    @Resource
    private ISystemRemote systemRemote;
    @Resource
    private AuthorityService authorityService;

    /**
     * 员工注册
     */
    @Override
    public Account employeeRegister(Organize organize, Account employee, String[] jurisdictionIds) {
        /// ### 检查账户信息是否存在
        Account extAccount = this.getAccountByUsername(employee.getUsername());
        if (extAccount != null) throw new BusinessException("注册的账号已存在，不要重复注册！");
        if (employee.getPhone() != null) {
            Account pheAccount = this.getAccountByPhone(employee.getPhone(), organize.getUserType());
            if (pheAccount != null) throw new BusinessException("该手机号已被注册！请直接登录或更换手机号");
        }
        // ### 如果存在手机号相同的已删除账号，采用账户覆盖，不重新建立账户，部分信息，如认证功能会得到恢复
//        List<Account> phoneAccList = getLogicAccountByPhone(employee.getPhone());
//        if (phoneAccList.size() > 0) {
//            employee.setId(ArrayUtil.first(phoneAccList).getId());
//            accountMapper.recoveryById(employee.getId());
//        }
        // #### 初始化信息
        employee.setOrganizeId(organize.getId());
        employee.setOrganizeName(organize.getOrganizeName());
        employee.setUserType(organize.getUserType());
        employee.setOrganType(organize.getOrganType());
        employee.setSuperiorPlatId(organize.getSuperiorPlatOrganizeId());
        employee.setSuperiorPlatName(organize.getSuperiorPlatOrganizeName());
        employee.setOrganizeManagerUserId(organize.getManagerUserId());
        employee.setOrganizeManagerUserName(organize.getManagerUserName());
        employee.setUserState(Account.UserState.enable);
        // #### 发送初始化密码
        String initPassword = employee.getPassword();
//        String msg = "您的管理员：%s 已成功为您注册%s成员账户，登录账号：%s，初始密码：%s，请及时登录并完成密码修改！";
//        String fmtMsg = String.format(msg, organize.getManagerUserName(), organize.getOrganizeName(), employee.getUsername(), initPassword);
//        messageRemote.sendPhoneMessage(employee.getPhone(), fmtMsg);
        // #### 注册完成
        employee.setPassword(AppUtil.md5(initPassword));
        employee.setAddUserId(organize.getManagerUserId());
        employee.setCreateTime(new Date());
        if (employee.getId() == null) accountMapper.insert(employee);
        else accountMapper.updateById(employee);
        if(jurisdictionIds!=null){
            List<Jurisdiction> jurisdictionList=ParamUtil.isSuccess(systemRemote.getJurisdictionListByIds(String.join(",",jurisdictionIds)));
            if(jurisdictionList!=null&& !jurisdictionList.isEmpty()){
                authorityService.saveAuthority(employee,jurisdictionList);
            }
        }
        return employee;
    }

    /**
     * 新 登录授权
     */
    @Override
    public void login(Account account, HttpServletRequest request) {
        account.setLoginIps(AppUtil.getIp(request));
        account.setLoginCount(account.getLoginCount() + 1); // 登录次数加1
        account.setLastLoginTime(new Date());
        account.setUpdateTime(new Date());
        accountMapper.updateById(account);
        //更新授权信息  //### 授权信息，保存的是授权API链接集合，用于网关鉴权
//        if (account.getUserType() != UserType.adminUser) {
//            Organize organize = organizeService.getOrganizeById(account.getOrganizeId());
//            if (organize.getMemberTypeId() == null) throw new BusinessException("没有会员权限，请联系上级平台！");
//            List<String> apiCodeList = functionGrantService.getGrantFunctionApiCodeList(organize.getMemberTypeId());
//            if (account.getToken() != null) UserUtil.saveGrantApiUrlList(account.getToken(), apiCodeList);
//            if (account.getRoleType() == RoleType.manager) {
//                //管理员默认获得组织所有权限，此方法初始化管理员角色时使用
//                grantRoleMenuService.initGrantRoleMenuList(account.getRoleId(), organize.getMemberTypeId());
//            }
//        }
//        //生成登录日志
//        String customerIp = AppUtil.getIp(request);
//        boolean mobile = request.getHeader(HttpConstant.MOBILE) != null;
//        OperateLog operateLog = new OperateLog();
//        operateLog.setOptUserId(account.getId());
//        operateLog.setOptToken(account.getToken());
//        operateLog.setOptIp(customerIp);
//        operateLog.setSuperiorPlatId(account.getSuperiorPlatId());
//        operateLog.setOptUserName(account.getName() == null ? account.getUsername() : account.getName());
//        operateLog.setOptDeviceType(mobile ? OperateLog.DeviceType.mobile : OperateLog.DeviceType.web);
//        operateLog.setOperateSite(request.getRequestURI());
//        operateLog.setOptTime(new Date());
//        operateLogRepository.save(operateLog);
    }

    /**
     * 人脸识别
     */
    @Override
    public double faceSimilarityScore(Account account, String base64FaceImg) {

        return 0;
    }

    /**
     * 新：录入高德终端信息
     */
    @Override
    public void checkGeoTerminal(Account userInfo) {
        //不要判断 终端ID为不为空，因为，服务ID变化后，终端ID会无效，把需不需要丢给GPS端
        if (userInfo.getUserType() == UserType.truckerUser) {
            Map<String, String> map = ParamUtil.isSuccess(gpsRemote.autoCreateTrackTerminal(userInfo.getSuperiorPlatId(), userInfo.getId()));
            userInfo.setGeoServiceId(map.get("geoServiceId"));
            userInfo.setGeoTerminalId(map.get("geoTerminalId"));
            accountMapper.updateById(userInfo);
        }
    }

    //-------------------------------------------账户找查区:------------------------------------------------

    /**
     * 根据手机号获取已经逻辑删除的账户
     * 全网唯一一个可以使用删除数据恢复的方法
     */
    @Override
    public List<Account> getLogicAccountByPhone(String phone) {
        return accountMapper.getLogicAccountByPhone(phone);
    }

    /**
     * 账户找查02: 账户找查 用户名
     */
    @Override
    public Account getAccountByUsername(String username) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return accountMapper.selectOne(queryWrapper);
    }

    /**
     * 账户找查03: 微信ID
     */
    @Override
    public Account getAccountByWechatId(String wechatId) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("wechat_id", wechatId);
        return accountMapper.selectOne(queryWrapper);
    }

    /**
     * 账户找查04: 鉴权token
     */
    @Override
    public Account getUserAccountByToken(String token) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("token", token);
        return accountMapper.selectOne(queryWrapper);
    }

    /**
     * 账户找查 手机号
     */
    @Override
    public Account getAccountByPhone(String phone, UserType userType) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        queryWrapper.eq("user_type", userType);
        return accountMapper.selectOne(queryWrapper);
    }

    /**
     * 账户找查 ID
     */
    @Override
    public Account getAccountById(String accountId) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", accountId);
        return accountMapper.selectOne(queryWrapper);
    }

    /**
     * 账户找查 ApiKey
     */
    @Override
    public Account getAccountByApiKey(String apiKey) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("secret_key", apiKey);
        return accountMapper.selectOne(queryWrapper);
    }

    /***
     * 账户找查 系统顶级管理用户
     * */
    @Override
    public Account getSystemAdminUser() {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_type", UserType.adminUser);
        queryWrapper.eq("role_type", RoleType.manager);
        return accountMapper.selectOne(queryWrapper);
    }

    /***
     * 账户找查 系统易林用户
     * */
    @Override
    public Account getSystemYilinUser() {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_type", RoleType.manager);
        return accountMapper.selectOne(queryWrapper);
    }

    /**
     * 批量账户找查: 角色id
     */
    @Override
    public List<Account> getAccountByRoleId(String roleId) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", roleId);
        return accountMapper.selectList(queryWrapper);
    }

    /**
     * 批量账户找查 组织获取员工
     */
    @Override
    public List<Account> getEmployeeByOrganizeId(String organizeId) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("organize_id", organizeId);
        queryWrapper.orderByAsc("role_type");
        List<Account> accounts = accountMapper.selectList(queryWrapper);
        for (Account account : accounts) { //放在控制层
            List<AuthStatusData> authStatusDataList = authService.getUserAuthStatus(account);
            account.setAuthStatusList(authStatusDataList);
            account.setSafePassword(null);
            account.setPassword(null);
            account.setSecretKey(null);
            account.setFingerprintSecretKey(null);
        }
        return accounts;
    }

    /**
     * 批量账户找查 组织获取员工
     */
    @Override
    public List<Account> getAccountByOrganizeId(String organizeId) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("organize_id", organizeId);
        return accountMapper.selectList(queryWrapper);
    }

    /**
     * 账户找查 批量获取Account
     */
    @Override
    public List<Account> getAccountListByIds(String[] accountIds) {
        List<String> stringList = ArrayUtil.initList(accountIds);
        return accountMapper.selectBatchIds(stringList);
    }

    /**
     * 账户找查 获取子平台用户信息
     */
    @Override
    public PageData<Account> getAccountChildPage(Account query, Integer start, Integer limit) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("organize_id", query.getOrganizeId());
        return accountMapper.selectPage(new PageData<>(start, limit), queryWrapper);
    }

    /**
     * 账户找查 部门获取账户
     */
    @Override
    public List<Account> getAccountList(String departmentId) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("department_Id", departmentId);
        return accountMapper.selectList(queryWrapper);
    }

    /**
     * 获取省运管未创建账户
     * 司机信息单
     */
    @Override
    public List<Account> getErrorTmsAccount() {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_type", UserType.truckerUser);
        queryWrapper.eq("tms_driver_data_state", Account.TmsDriverDataState.wait);
        queryWrapper.or().eq("tms_driver_data_state", Account.TmsDriverDataState.error);
        return accountMapper.selectList(queryWrapper);
    }

    //----------------------------------------------账户变更区--------------------------------------------------

    /**
     * SQL更新账户
     */
    @Override
    public Account saveOrUpdateAccount(Account account, Account loginUser) {
        if (account.getId() != null) {
            account.setUpdateUserId(loginUser.getId());
            account.setUpdateTime(new Date());
        } else {
            account.setAddUserId(loginUser.getId());
            account.setCreateTime(new Date());
        }
        saveOrUpdate(account);
        return account;
    }

    /**
     * 更新信用数据评分
     */
    @Override
    public void updateUserCredit(Account loginUser, String accountId, Double diffCredit, String reason) {
        Account local = accountMapper.selectById(accountId);
        if (!local.getSuperiorPlatId().equals(loginUser.getOrganizeId())) {
            throw new BusinessException("仅能用户所属平台能操作用户信用信息！");
        }
        if (reason == null) reason = "不明原因";
        CreditRecord creditRecord = new CreditRecord();
        creditRecord.setAccountId(accountId);
        creditRecord.setAccountName(local.getName());
        creditRecord.setOrganizeId(local.getOrganizeId());
        creditRecord.setOrganizeName(local.getOrganizeName());
        creditRecord.setUserType(local.getUserType());
        creditRecord.setHandleCredit(diffCredit);//本次操作分数
        creditRecord.setHandlePreCredit(local.getCredit());
        creditRecord.setHandleLaterCredit(local.getCredit() + diffCredit);
        creditRecord.setHandleTime(new Date());
        creditRecord.setHandleReason(reason);
        creditRecord.setHandleUserId(loginUser.getId());
        creditRecord.setHandleUserName(loginUser.getName());
        creditRecordMapper.insert(creditRecord);
        local.setCredit(local.getCredit() + diffCredit);
        accountMapper.updateById(local);
    }

    /***
     * 转让管理员
     * */
    @Override
    public void transferManager(Account manager, Account account) {
        Organize organize = organizeService.getOrganizeById(manager.getOrganizeId());
        //第一步：交换管理员/员工角色
//        UserRole managerRole = roleService.getById(manager.getRoleId());
//        UserRole employeeRole = roleService.getById(account.getRoleId());
//        account.setRoleId(managerRole.getId());
//        account.setRoleName(managerRole.getName());
//        account.setRoleType(managerRole.getRoleType());
//        manager.setRoleId(employeeRole.getId());
//        manager.setRoleName(employeeRole.getName());
//        manager.setRoleType(employeeRole.getRoleType());
        //第二步：修改组织信息
        organize.setManagerUserId(account.getId());
        organize.setManagerUserName(account.getName());
        organize.setManagerUserPhone(account.getPhone());
        organize.setManagerUserEmail(account.getEmail());
        //第三步：修改所有员工管理员
        List<Account> employeeList = getEmployeeByOrganizeId(organize.getId());
        for (Account employee : employeeList) {
            employee.setOrganizeManagerUserId(account.getId());
            employee.setOrganizeManagerUserName(account.getName());
            updateById(employee);
        }
        //第四步：修改集团下属集团上级管理员
        List<Organize> organizeList = organizeService.getGroupOrganizeList(organize.getId());
        for (Organize childOrganize : organizeList) {
            childOrganize.setGroupOrganizeManagerUserId(account.getId());
            childOrganize.setGroupOrganizeManagerUserName(account.getName());
            organizeService.updateById(childOrganize);
        }
        //第五步：重置身份证认证，清除电子签名和税务认证，
        IdCard idCard = authService.getIdCardByUserId(account.getId());
        if (idCard != null) {
            idCard.setAuthStatus(AuthStatus.notApply);
            authService.saveIdCardAuth(account, idCard);
        }
        StampPersonalSignet stampPersonalSignet = authService.getStampPersonalSignetByOrganizeId(organize.getId());
        if (stampPersonalSignet != null) {
            stampPersonalSignet.setAuthStatus(AuthStatus.notApply);
            authService.saveStampPersonalSignetAuth(account, stampPersonalSignet);
        }
        TaxCertification taxCertification = authService.getTaxCertificationByOrganizeId(organize.getId());
        if (taxCertification != null) {
            taxCertification.setAuthStatus(AuthStatus.notApply);
            authService.saveTaxCertificationAuth(account, taxCertification);
        }
        //第六步：清除银行卡、钱包等信息【如果有钱包的话】
        capitalRemote.removeBankCardList();
        updateById(manager);
        updateById(account);
        organizeService.updateById(organize);
    }

    /**
     * 账户注销
     */
    @Override
    public void scrapAccount(Account manager, Account account) {
        //需逻辑删除所有证件数据
        IdCard idCard = authService.getIdCardByUserId(account.getId());
        if (idCard != null) authService.deleteIdCardById(idCard);
        DrivingLicense drivingLicense = authService.getDrivingLicenseByUserId(account.getId());
        if (drivingLicense != null) authService.deleteDrivingLicenseById(drivingLicense);
        QualificationCert qualificationCert = authService.getQualificationCertByUserId(account.getId());
        if (qualificationCert != null) authService.deleteDrivingLicenseById(drivingLicense);
        //实体中含有逻辑删除字段，此数据不会被真实删除
        authorityService.deleteAuthorityListByAccountId(account.getId());
        accountMapper.deleteById(account);
        if (account.getRoleType() == RoleType.employee) {
            String msg = "尊敬的用户您好，您的管理员：%s 已将你移出组织：%s，您的账户已被强制注销，下次使用时需要重新注册账号！";
            String fmtMsg = String.format(msg, manager.getName(), manager.getOrganizeName());
//            messageRemote.sendPhoneMessage(account.getPhone(), fmtMsg);
        }
    }

    /**
     * 安全锁定次日恢复任务
     */
    @Override
    public void autoSetSafeEnable() {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("safe_disabled", true);
        List<Account> accountList = accountMapper.selectList(queryWrapper);
        for (Account account : accountList) {
            account.setSafeDisabled(false);
            accountMapper.updateById(account);
        }
    }

    /**
     * 更新账户累计信息
     */
    @Override
    public void updateUserAccrual(Account loginUser, String accountId, UserAccrual param) {
        Account localAccount = getAccountById(accountId);
        if (localAccount == null || param == null) return;
//        if (!localAccount.getSuperiorPlatId().equals(loginUser.getOrganizeId())) {
//            throw new BusinessException("仅能用户所属平台能操作用户信息！");
//        }
        //-------------------------------统计累计信息---------------------------------------
        localAccount.setGoodAppraiseCount(localAccount.getGoodAppraiseCount() + param.getDiffGoodAppraiseCount());
        localAccount.setMidAppraiseCount(localAccount.getMidAppraiseCount() + param.getDiffMidAppraiseCount());
        localAccount.setBadAppraiseCount(localAccount.getBadAppraiseCount() + param.getDiffBadAppraiseCount());
        localAccount.setComplaintsCount(localAccount.getComplaintsCount() + param.getDiffComplaintsCount());
        localAccount.setArbitrationCount(localAccount.getArbitrationCount() + param.getDiffArbitrationCount());
        localAccount.setViolationCount(localAccount.getViolationCount() + param.getDiffViolationCount());
        accountMapper.updateById(localAccount);
    }

    /**
     * 更新账户2
     */
    @Override
    public void updateAccount(Account loginUser, Account param, Account localAccount) {
        if (param.getUserState() != null) localAccount.setUserState(param.getUserState());
        if (StringUtil.isNotEmpty(param.getUsername())) {
            Account other = accountMapper.selectOne(new QueryWrapper<Account>().eq("username", param.getUsername()));
            if (other != null && !other.getId().equals(localAccount.getId()))
                throw new BusinessException("您修改的账号已被占用，请重新更换");
            localAccount.setUsername(param.getUsername());
        }
        //------------------------------基本型信息-------------------------------------
        if (StringUtil.isNotEmpty(param.getPhone())) localAccount.setPhone(param.getPhone());
        if (StringUtil.isNotEmpty(param.getEmail())) localAccount.setEmail(param.getEmail());
        if (StringUtil.isNotEmpty(param.getWechatId())) localAccount.setWechatId(param.getWechatId());
        if (StringUtil.isNotEmpty(param.getAddress())) localAccount.setAddress(param.getAddress());
        if (StringUtil.isNotEmpty(param.getName())) localAccount.setName(param.getName());
        if (StringUtil.isNotEmpty(param.getAvatar())) localAccount.setAvatar(param.getAvatar());
        if (param.getTmsDriverDataState() != null) localAccount.setTmsDriverDataState(param.getTmsDriverDataState());

        //-------------------------------API秘钥---------------------------------------
        if (localAccount.getRoleType() == RoleType.api && StringUtil.isNotEmpty(param.getPublicKey())) {
            localAccount.setPublicKey(param.getPublicKey());
            String secretKey = RedisClient.getInstance().hget(RedisKeys.ACCOUNT_API_PAIR_KEY, param.getPublicKey());
            localAccount.setSecretKey(secretKey);
        }
        if (localAccount.getRoleType() == RoleType.manager) {
            Organize organize = organizeService.getOrganizeById(localAccount.getOrganizeId());
            if (StringUtil.isNotEmpty(param.getName())) organize.setManagerUserName(param.getName());
            if (StringUtil.isNotEmpty(param.getAvatar())) organize.setManagerUserAvatar(param.getAvatar());
            if (StringUtil.isNotEmpty(param.getPhone())) organize.setManagerUserPhone(param.getPhone());
            organizeService.updateById(organize);
        }
        localAccount.setUpdateUserId(loginUser.getId());
        localAccount.setUpdateTime(new Date());
        accountMapper.updateById(localAccount);
    }

    @Override
    @Transactional
    public void updateAccountAndOrganize(Account loginUser, Account account, Organize organize) {
        if (organize.getId() != null) {
            if (loginUser.getRoleType() != RoleType.manager) {
                throw new BusinessException("您没有权限修改");
            }
            Organize organizeOld = organizeService.getOrganizeById(organize.getId());
            organizeOld.setOrganizeTel(organize.getOrganizeTel());
            organizeOld.setAddress(organize.getAddress());
            organizeOld.setOrganizeLogo(organize.getOrganizeLogo());
            organizeOld.setIntroduction(organize.getIntroduction());
            organizeOld.setUpdateUserId(loginUser.getId());
            organizeOld.setUpdateTime(new Date());
            organizeService.updateById(organizeOld);
        }
        Account accountOld = getAccountById(account.getId());
        accountOld.setAvatar(account.getAvatar());
        accountOld.setEmail(account.getEmail());
        accountOld.setAddress(account.getAddress());
        accountMapper.updateById(accountOld);
    }

    /**
     * 安全操作 安全密码次数验证
     */
    @Override
    public void verifySvePassword(Account loginUser, String savePassword) {
        Account account = this.getAccountById(loginUser.getId());
        if (account.getSafePassword() == null) {
            throw new BusinessException(BaseCode.NO_PASS_ERR, "你没有设置安全密码！");
        }
        if (account.getSafeDisabled()) {
            throw new BusinessException(account.getSafeFailReason());
        }
        if (!AppUtil.md5(savePassword).equals(account.getSafePassword())) {
            account.setSafeFailCount(account.getSafeFailCount() + 1);
            if (account.getSafeFailCount() <= 3) {
                String errTip = "安全密码错误，您今日已输错%s次，超过3次将被禁用操作";
                accountMapper.updateById(account);
                throw new BusinessException(String.format(errTip, account.getSafeFailCount()));
            }
            // ### 超过三次 禁用操作
            account.setSafeFailCount(0);//禁用账户，还原次数
            account.setSafeDisabled(true);
            account.setSafeFailReason("密码输入错误超过3次，已被禁用安全操作");
            accountMapper.updateById(account);
            throw new BusinessException("您今日输错安全密码超过3次，已被禁用安全操作");
        }
    }

    /**
     * 安全操作 指紋密码次数验证
     */
    @Override
    public void verifySvePublicKey(Account loginUser, String fingerprintKey) {
        Account account = this.getAccountById(loginUser.getId());
        if (account.getFingerprintSecretKey() == null) {
            throw new BusinessException(BaseCode.NO_PASS_ERR, "你没有设置指纹密码！");
        }
        if (account.getSafeDisabled()) {
            throw new BusinessException(account.getSafeFailReason());
        }
        String token = Md5Util.md5(EncryptUtils.aesEncrypt(account.getDeviceId(), null));
        String publicKey = EncryptUtils.aesDecrypt(fingerprintKey, token);
        String privateKey = EncryptUtils.aesDecrypt(account.getFingerprintSecretKey(), token);
        if (!EncryptUtils.validRSAKeyPairMatch(publicKey, privateKey)) {
            account.setSafeFailCount(account.getSafeFailCount() + 1);
            if (account.getSafeFailCount() <= 3) {
                String errTip = "指纹验证错误，您今日已验证失败%s次，超过3次将被禁用操作";
                accountMapper.updateById(account);
                throw new BusinessException(String.format(errTip, account.getSafeFailCount()));
            }
            // ### 超过三次 禁用操作
            account.setSafeFailCount(0);//禁用账户，还原次数
            account.setSafeDisabled(true);
            account.setSafeFailReason("指纹验证错误超过3次，已被禁用安全操作");
            accountMapper.updateById(account);
            throw new BusinessException("您今日指纹验证错误超过3次，已被禁用安全操作");
        }
    }

    //------------------------------------------------------------------------------------------------------------

    @Override
    public List<Contact> getContactsList(String userId, Contact query) {
        QueryWrapper<Contact> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_id", userId);
        queryWrapper.eq("contacts_type", query.getContactsType());
        QueryUtil.andQueryWrapper(queryWrapper, query);
        return contactMapper.selectList(queryWrapper);
    }

    @Override
    public Contact getContactById(String contactId) {
        return contactMapper.selectById(contactId);
    }

    @Override
    public void saveContacts(Contact contact) {
        if (contact.getId() != null) {
            contact.setUpdateTime(new Date());
            contactMapper.updateById(contact);
        } else {
            contact.setCreateTime(new Date());
            contactMapper.insert(contact);
        }
    }

    @Override
    public void deleteContacts(Contact contact) {
        if (contact.getId() != null) {
            contactMapper.deleteById(contact);
        }
    }

    /**
     * 获取极光推送ID集合
     */
    @Override
    public List<String> getPushIdList() {
        return accountMapper.getPushIdList();
    }

    @Override
    public List<String> getPushIdListByUserType(UserType type) {
        return accountMapper.getPushIdListByUserType(type);
    }

    /**
     * 根据用户类型获取pushIds
     */
    @Override
    public String[] getPushIdsByUserType(Account loginUser, UserType userType) {
        List<String> pushIdsByUserType = accountMapper.getPushIdsByUserType(loginUser, userType);
        return pushIdsByUserType.toArray(new String[0]);
    }

    @Override
    public void test002(String organize01, String organize02, String organizeName) {


        List<Cooperate> shipperOrganizeId = cooperateMapper.selectList(new QueryWrapper<Cooperate>().eq("shipper_organize_id", organize01));

        for (Cooperate cooperate : shipperOrganizeId) {
            cooperate.setShipperOrganizeId(organize02);
            cooperate.setShipperOrganizeName(organizeName);
            String uUid = getUUid();
            cooperate.setId(uUid);
            cooperateMapper.insert(cooperate);
        }


    }

    private String getUUid() {
        UUID uuid = UUID.randomUUID();
        String str = uuid.toString();
        return str.replace("-", "");
    }

}

